/************************************
 * Package: RGcpp					*
 * Authors: Rui Eduardo Gouveia Gil	*
 * Date: 2010						*
 ************************************/
#include "rgcpp/sys/JobQueue.h"

namespace rgcpp
{

JobQueue::JobQueue()
{
	this->running = true;
}

JobQueue::~JobQueue()
{

}

void JobQueue::release()
{
	boost::mutex::scoped_lock lock(mut);
	this->running = false;
	this->cond.notify_all();
}

void JobQueue::addJob(boost::shared_ptr<Job> job)
{
	boost::mutex::scoped_lock lock(mut);
	this->queue.push(job);
	this->cond.notify_one();
}

boost::shared_ptr<Job> JobQueue::getJob()
{
	boost::xtime xt;
	xt.nsec = 0;

	while(true)
	{
		boost::mutex::scoped_lock lock(mut);

		if(!running) return boost::shared_ptr<Job>();

		while(!queue.size() && running)
			cond.wait(lock);

		if(!running) return boost::shared_ptr<Job>();

		boost::shared_ptr<Job> obj = queue.top();

		if(obj.get() == NULL)
			continue;

		xt.sec = obj->getExecuteTime();

		cond.timed_wait(lock,xt);

		if(queue.empty() || queue.top().get() == NULL || obj->getJobId() != queue.top()->getJobId())
			continue;

		time_t current;
		time(&current);
		if(current < obj->getExecuteTime())
			continue;

		queue.pop();

		return obj;
	}
}

int JobQueue::size()
{
	boost::mutex::scoped_lock lock(mut);
	return this->queue.size();
}
}
